package com.bluetoothsms.x86;

import java.io.IOException;
import java.util.Enumeration;

import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DataElement;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;

import com.bluetoothsms.common.Common;

public class ConnectionThread extends Thread implements DiscoveryListener {

	private final static UUID BT_CONN_UUID = new UUID(Common.UUID.replaceAll(
			"-", ""), false);

	private final BluetoothSMSx86 mCallback;
	private final DiscoveryAgent mAgent;
	private final RemoteDevice mDevice;

	private String mErrorMsg = "";
	private ServiceRecord mServiceRecord;
	private int mTransID = -1;
	private StreamConnection mConnection;

	public ConnectionThread(BluetoothSMSx86 callback, DiscoveryAgent agent,
			RemoteDevice device) {
		mCallback = callback;
		mAgent = agent;
		mDevice = device;
	}

	public void run() {
		// Service suchen und verbinden
		findService();
	}

	public synchronized void cancel() {
		if (mTransID > -1) {
			mAgent.cancelServiceSearch(mTransID);
			mTransID = -1;
		}
	}

	public String getErrorMessage() {
		return mErrorMsg;
	}

	/*
	 * private void findDevice() { mDevice = null;
	 * 
	 * try { mAgent.startInquiry(DiscoveryAgent.LIAC, this); } catch
	 * (BluetoothStateException e) { mErrorMsg = e.getMessage();
	 * mCallback.onConnected(null); } }
	 */

	private void findService() {
		mServiceRecord = null;

		try {
			UUID[] uuids = new UUID[] { BT_CONN_UUID };
			mTransID = mAgent.searchServices(null, uuids, mDevice, this);

		} catch (BluetoothStateException e) {
			mErrorMsg = e.getMessage();
			mCallback.onConnected(null);
		}
	}

	@Override
	public void deviceDiscovered(RemoteDevice remoteDevice, DeviceClass arg1) {
		// if (remoteDevice.getBluetoothAddress().equals(mMacAddress))
		// mDevice = remoteDevice;
	}

	@Override
	public void inquiryCompleted(int param) {
		/*
		 * switch (param) { case DiscoveryListener.INQUIRY_COMPLETED: // Inquiry
		 * completed normally if (mDevice != null) { // Service suchen
		 * findService(); } else { mErrorMsg = "Device not found!";
		 * mCallback.onConnected(null); } break;
		 * 
		 * case DiscoveryListener.INQUIRY_ERROR: // Error during inquiry
		 * mErrorMsg = "Inquiry error!"; mCallback.onConnected(null); break;
		 * 
		 * case DiscoveryListener.INQUIRY_TERMINATED: // Inquiry terminated by
		 * // agent.cancelInquiry() mErrorMsg = "Inquiry terminated!";
		 * mCallback.onConnected(null); break; }
		 */
	}

	@Override
	public void serviceSearchCompleted(int transID, int respCode) {
		switch (respCode) {
		case DiscoveryListener.SERVICE_SEARCH_COMPLETED:
			if (mServiceRecord != null) {
				String url = mServiceRecord.getConnectionURL(
						ServiceRecord.AUTHENTICATE_ENCRYPT, false);

				try {
					// Verbindung aufbauen
					mConnection = (StreamConnection) Connector.open(url);
				} catch (IOException e) {
					mErrorMsg = e.getMessage();
				}
			} else
				mErrorMsg = "The service was not found!";

		case DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE:
			mErrorMsg = "Device not Reachable!";
			break;

		case DiscoveryListener.SERVICE_SEARCH_ERROR:
			mErrorMsg = "Service serch error!";
			break;

		case DiscoveryListener.SERVICE_SEARCH_NO_RECORDS:
			mErrorMsg = "No records returned!";
			break;

		case DiscoveryListener.SERVICE_SEARCH_TERMINATED:
			mErrorMsg = "Search cancelled!";
			break;
		}

		if (mTransID > -1) {
			mTransID = -1;
			mCallback.onConnected(mConnection);
		}
	}

	@Override
	public void servicesDiscovered(int transID, ServiceRecord[] serviceRecord) {
		for (ServiceRecord r : serviceRecord) {
			DataElement dataElement = r.getAttributeValue(1);

			if (dataElement == null
					|| dataElement.getDataType() != DataElement.DATSEQ
					|| dataElement.getSize() == 0)
				return;

			Object value = dataElement.getValue();

			if (value == null)
				return;

			for (@SuppressWarnings("unchecked")
			Enumeration<Object> e = (Enumeration<Object>) value; e
					.hasMoreElements();) {
				Object element = e.nextElement();

				if (!(element instanceof DataElement)) {
					continue;
				}

				dataElement = (DataElement) element;

				if ((dataElement.getDataType() == DataElement.UUID)) {
					if (BT_CONN_UUID.equals(dataElement.getValue())) {
						mServiceRecord = r;
					}
				}
			}

		}
	}

}
